#pragma once

#include <asm-generic/errno-base.h>
#include <asm-generic/errno.h>
#include<iostream>
#include<memory>
#include"Reactor.hpp"
#include "Common.hpp"
#include "Connection.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"
#include"Socket.hpp"
#include"IOService.hpp"
#include"Calculator.hpp"
#include "Protocol.hpp"

//专门获取链接
using namespace SocketModule;
class Listener:public Connection
{
public:
    Listener(int port)
    :_listensock(std::make_unique<TcpSocket>())
    ,_port(port)
    {
        _listensock->BuildTcpSocketMethod(_port);
        SetSockfd(_listensock->Fd());
        SetEvents(EPOLLIN | EPOLLET);
    }

    //回调方法
    virtual void Recver() override
    {
        //读事件就绪，listensock就绪
        //IO处理----获取新连接
        //解决一次来多个连接，读完这些连接
        //不断循环读取
        while(true)
        {
            InetAddr peer;
            int aerrno = 0;
            //accept 非阻塞的时候就是在IO，像处理read一样处理accepter
            int sockfd = _listensock->Accepter(&peer,&aerrno);;
            if(sockfd > 0)
            {
                //success
                //不能直接处理获取到的连接，将获取到的sockfd添加到epoller
                //epollserver仅认识connection
                //1.将connection传进来利用回指针调用Insert将sockfd插入到epoller中  2.(传入方法：继承Connection)(选这个)

                //普通文件描述符,处理IO，利用IOS.hpp进行连接处理
                //1.设置文件描述符非阻塞
                SetNonBlock(sockfd);
                //2.将sockfd包装成connection
                auto con = std::make_shared<IOService>(sockfd);
                con->RegisterOnMessage(HanderRequest);
                //3.插入
                GetOwner()->InsertConnection(con);


            }
            else
            {
                //读取完了
                if(aerrno == EAGAIN || aerrno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accepter all connection..done";
                    break;
                }
                //被打断
                else if(aerrno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accepter intr by singal,contunue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::WARNING) << "accepter error...ignore";
                    break;
                }
            }
        }
    }
    virtual void Sender() override
    {}

    virtual void Excepter() override
    {}

    int Fd() {return _listensock->Fd();}

    ~Listener()
    {
        _listensock->Close();
    }
    
private:
    std::unique_ptr<Socket> _listensock;
    int _port;
};